home *** CD-ROM | disk | FTP | other *** search
/ ftp.whtech.com / ftp.whtech.com.7z / ftp.whtech.com / datasheets and manuals / Hardware / WHT / scsi / dsr_sources_2_2001 / write < prev   
Encoding:
Text File  |  2006-10-19  |  15.6 KB  |  615 lines

  1. * I/O Opcode 3 - WRITE
  2. *
  3. * This routine will store a record into the file buffer providing
  4. * the file has been open for writing.  If the buffer is full, it
  5. * will call FLUSH to write it out to disk and then start a new
  6. * buffer.
  7. *
  8.  
  9. WRITE0 ANDI R12,>FF00
  10.        AI   R12,24
  11.        LDCR @B02,4           Select RAM bank 2
  12.        BLWP @IFO             See if file is open
  13.        JEQ  WRITE2
  14.  
  15. WRITE1 BL   @DSRERR
  16.        DATA >0700            File error
  17.  
  18. * If the file is open for input mode, error.  All other modes
  19. * allow write access.
  20. WRITE2 CB   @56(R5),@B02     Input mode
  21.        JNE  WRITE3
  22.        BL   @DSRERR
  23.        DATA >0200            Bad open attribute?
  24.  
  25. * Now check to see if we're doing sequential or random I/O
  26.  
  27. WRITE3 LDCR @ZERO,4
  28.        MOVB @PABBUF+1,R1
  29.        ANDI R1,>0100
  30.        JEQ  WRITE4
  31.  
  32. * We're handling relative I/O now!  7-2-95
  33.  
  34.        B    @WRIT50
  35.  
  36. * The first thing we do is see if we're working on an AU.  If
  37. * not, we assume this is the first record being written to this
  38. * file.  If the data chain is empty, we allocate an AU for it.
  39. * Otherwise, we use the AU that's already allocated.
  40.  
  41. WRITE4 LDCR @B02,4           Select RAM bank 2
  42.        C    @50(R5),@ZERO    See if current AU=0
  43.        JEQ  WRT4Z
  44.        B    @WRIT10
  45. WRT4Z
  46. * Let's see if this file has any AU's allocated for it already.
  47. *
  48.        MOV  @4(R5),R1        Get FDR address
  49.        LDCR @2(R5),4         Select bank with FDR
  50.        MOV  @40(R1),R7       Get 1st AU in chain
  51.        JEQ  WRIT4A
  52.        LDCR @B02,4
  53.        MOV  R7,@50(R5)       Save the AU
  54.  
  55. * If we're in update mode and the file has fixed length records,
  56. * we should read in the data to the buffer.
  57.  
  58.        CB   @ZERO,@56(R5)    See if update mode
  59.        JNE  WRIT6B
  60.        LDCR @2(R5),4
  61.        MOVB @12(R1),R0       Get file flags
  62.        ANDI R0,8000
  63.        JNE  WRIT6B
  64.        LDCR @B04,4           We have to read it in!
  65.        MOV  R6,R3
  66.        SRL  R3,8
  67.        SLA  R3,1
  68.        MPY  @SAUTBL(R3),R7
  69.        LI   R3,SECBUF
  70.        SRL  R8,1
  71.        JNC  WRT4A
  72.        AI   R3,>100
  73. WRT4A  SRL  R7,1
  74.        JNC  WRT4B
  75.        AI   R8,>8000
  76. WRT4B  LDCR @ZERO,4
  77.        BLWP @BANKIT
  78.        DATA SCSIRD
  79.        JEQ  WRT4C
  80.        BL   @DSRERR
  81.        DATA >0600            Device error
  82.  
  83. WRT4C  LDCR @B02,4
  84.        MOV  @6(R5),R7        Get Buffer address
  85.        MOVB @3(R5),R8        Get buffer bank
  86. WRT4D  LDCR @ZERO,4
  87.        MOV  *R3+,R0
  88.        LDCR R8,4
  89.        MOV  R0,*R7+
  90.        CI   R3,SECBUF+512
  91.        JNE  WRT4D
  92.        JMP  WRIT6B
  93.  
  94. * OK.  Let's go out and allocate the 1st AU for the file
  95.  
  96. WRIT4A MOV  R5,R0            Save pointer to cache entry
  97.  
  98.        CLR  R7               No preferred starting AU
  99.        LI   R8,1             We want 1 AU
  100.        LI   R3,256*8         AU boundry
  101.        LDCR @ZERO,4          Select RAM bank 0
  102.        BLWP @ALLOC
  103.        JEQ  WRITE5
  104.        BL   @DSRERR
  105.        DATA >0600            Device error
  106.  
  107. WRITE5 CI   R4,0             Make sure we got one
  108.        JNE  WRITE6
  109.  
  110.        BL   @DSRERR
  111.        DATA >0400            Out of space
  112.  
  113. WRITE6 LDCR @B02,4           Select RAM bank 2
  114.        MOV  R5,R2
  115.        MOV  R0,R5            Restore pointer
  116.  
  117.        MOV  R2,@50(R5)       Save current AU
  118.  
  119. * Put the AU in the data chain
  120.  
  121.        MOV  @4(R5),R1        Get pointer to FDR
  122.        LDCR @2(R5),4
  123.        MOV  R2,@40(R1)       Store AU in data chain
  124.        MOV  R2,@42(R1)
  125.        INC  @34(R1)          Increment # of AU's in FDR
  126.        LDCR @B04,4           Set # of sectors allocated
  127.        MOV  R6,R3
  128.        SRL  R3,8
  129.        SLA  R3,1
  130.        MOV  @SAUTBL(R3),R3
  131.        LDCR @B02,4
  132.        LDCR @2(R5),4
  133.        MOV  R3,@14(R1)
  134.  
  135. WRIT6B LDCR @B02,4
  136.        CLR  @52(R5)          Sector within AU = 0
  137.        CLR  @58(R5)          Buffer size = 256
  138.        MOV  @6(R5),@54(R5)   Pointer within buffer
  139.  
  140.        LDCR @2(R5),4         Select bank with FDR
  141.  
  142.        MOVB @12(R1),R3       If variable length records,
  143.        ANDI R3,>8000         Set sector # to one
  144.        JEQ  WRT6A
  145.        LI   R3,1
  146.        LDCR @B02,4
  147.        MOV  R3,@62(R5)
  148.  
  149. * See if we can use a 512 byte buffer
  150. *
  151. WRT6A  LDCR @B04,4           Select RAM bank 4
  152.        MOV  R6,R3
  153.        SRL  R3,8
  154.        SLA  R3,1
  155.        MOV  @SAUTBL(R3),R1
  156.        CI   R1,1
  157.        JEQ  WRITE8
  158.        ANDI R1,>0001
  159.        JEQ  WRITE7
  160.        ANDI R2,>0001
  161.        JNE  WRITE8
  162.  
  163. WRITE7 LDCR @B02,4           Select RAM bank 2
  164.        SETO @58(R5)
  165. WRITE8 B    @WRIT30
  166.  
  167.  
  168. * Here we check to see if there is enough room in the buffer
  169. * to hold the record.  In the case of variable length files,
  170. * we must also account for the record size byte and the
  171. * end of sector marker.
  172. *
  173. WRIT10 LDCR @B02,4
  174.        MOV  @4(R5),R1
  175.        LDCR @2(R5),4
  176.        MOVB @17(R1),R2       Get record size
  177.        MOVB @12(R1),R4       Get file flags
  178.  
  179.        LDCR @ZERO,4
  180.        CB   @PABBUF+5,R2     Make sure we're not trying
  181.        JL   WRIT11           to write more characters than
  182.        JEQ  WRIT11           the file allows
  183.  
  184.        BL   @DSRERR
  185.        DATA >0700            File error
  186.  
  187. WRIT11 SRL  R2,8
  188.        ANDI R4,>8000         Check for fixed or variable
  189.        JEQ  WRIT12
  190.  
  191.        MOVB @PABBUF+5,R2     Get character count from PAB
  192.        SRL  R2,8
  193.        INCT R2               Add in length byte and EOS marker
  194.  
  195. WRIT12
  196.  
  197. * We will now see if there's enough room in the buffer
  198.  
  199.        LDCR @B02,4            Select RAM bank 2
  200.        MOV  @54(R5),R1        Get pointer within buffer
  201.        S    @6(R5),R1         Subtract the base address
  202.        CI   R1,>200
  203.        JEQ  WRIT14
  204.        CI   R1,>100
  205.        JNE  WRT12A
  206.        C    @58(R5),@ZERO     See if buffer size is 256
  207.        JEQ  WRIT14            If so, read next sector
  208. WRT12A
  209.        MOV  @54(R5),R1
  210.        ANDI R1,>00FF
  211.        A    R2,R1
  212.        CI   R1,>100
  213.        JH   WRIT13
  214.        B    @WRIT30
  215.  
  216. * There is not enough room in the buffer to add one more
  217. * record.  First we check to see if the buffer size is 512
  218. * bytes.  If so, we see if we are in the first half and simply
  219. * adjust a couple of pointers to go to the second half of
  220. * the buffer.  Otherwise, we write the buffer out to disk
  221. * and start a new one.
  222.  
  223. WRIT13
  224.  
  225. * If we have variable length records,
  226. * we want to increment our sector #
  227.        LDCR @B02,4
  228.        MOV  @4(R5),R1        Get address of FDR
  229.        LDCR @2(R5),4         Select bank with FDR
  230.        MOV  @12(R1),R0       Get file flags
  231.        LDCR @B02,4           Select Bank 2 again
  232.        ANDI R0,>8000
  233.        JEQ  WRT13A
  234.        INC  @62(R5)          Increment sector #
  235. WRT13A
  236.        MOV  @58(R5),R1       Check for 512 byte buffer
  237.        JEQ  WRIT14
  238.  
  239.        MOV  @54(R5),R1       Get pointer in buffer
  240.        ANDI R1,>0100         Check what half we're in
  241.        JNE  WRIT14
  242.  
  243.        MOV  @54(R5),R1       Just go to 2nd half of buffer
  244.        ANDI R1,>FF00
  245.        AI   R1,>100
  246.        MOV  R1,@54(R5)
  247.  
  248.        B    @WRIT30
  249.  
  250. * Here we have to write the buffer out to disk.  We then
  251. * go to the next sector in the AU or next AU.  If there
  252. * are no more AU's, we have to allocate a new one and
  253. * put it at the end of the data chain
  254. *
  255. * If we are in update mode writing fixed length records,
  256. * we read the old data into the buffer.
  257.  
  258. WRIT14
  259.        BL   @FLUSH
  260.  
  261.        LDCR @B04,4           Select RAM bank 4
  262.        MOV  R6,R3            Get number of sectors / AU
  263.        SRL  R3,8
  264.        SLA  R3,1
  265.        MOV  @SAUTBL(R3),R3
  266.  
  267.        LDCR @B02,4           Select RAM bank 2
  268.        INC  @52(R5)          Go to next sector in AU
  269.        MOV  @6(R5),@54(R5)   Reset pointer within buffer
  270.        C    @58(R5),@ZERO    If buffer size is 512 bytes,
  271.        JEQ  WRIT15           then add another sector
  272.        INC  @52(R5)
  273. WRIT15 C    @52(R5),R3       See if we need to go to next AU
  274.        JL   WRT18A
  275.  
  276.        S    R3,@52(R5)
  277.  
  278. * We now have to search the data chain to see where our
  279. * AU is.  If it's at the end of the file, we have to
  280. * allocate a new AU.
  281.  
  282.        MOV  @50(R5),R2       Get current AU
  283.        MOV  @4(R5),R1        Get FDR address
  284.        AI   R1,42            Point to data chain (+2)
  285.        LDCR @2(R5),4
  286.  
  287. WRIT16 C    *R1,@ZERO        Are we at the end?
  288.        JEQ  WRIT17
  289.        C    *R1,R2           Is this our AU?
  290.        JEQ  WRIT19
  291.        AI   R1,4
  292.        JMP  WRIT16
  293.  
  294. WRIT17 INC  R2               Just go to next AU
  295. WRIT18 LDCR @B02,4
  296.        MOV  R2,@50(R5)
  297.  
  298.        CLR  @58(R5)          Set buffer size to 256
  299. WRT18A
  300.  
  301. * Here we check to see if we're in update mode
  302. * and have fixed length records.  If so, we want
  303. * to read the sector first
  304.  
  305.        LDCR @B02,4
  306.        CB   @ZERO,@56(R5)    See if update mode
  307.        JNE  WRT18F
  308.        LDCR @2(R5),4
  309.        MOVB @12(R1),R0       Get file flags
  310.        ANDI R0,8000
  311.        JNE  WRT18F
  312.        LDCR @B04,4           We have to read it in!
  313.        MOV  R6,R3
  314.        SRL  R3,8
  315.        SLA  R3,1
  316.        MPY  @SAUTBL(R3),R7
  317.        LI   R3,SECBUF
  318.        SRL  R8,1
  319.        JNC  WRT18B
  320.        AI   R3,>100
  321. WRT18B SRL  R7,1
  322.        JNC  WRT18C
  323.        AI   R8,>8000
  324. WRT18C LDCR @ZERO,4
  325.        BLWP @BANKIT
  326.        DATA SCSIRD
  327.        JEQ  WRT18D
  328.        BL   @DSRERR
  329.        DATA >0600            Device error
  330.  
  331. WRT18D LDCR @B02,4
  332.        MOV  @6(R5),R7        Get Buffer address
  333.        MOVB @3(R5),R8        Get buffer bank
  334. WRT18E LDCR @ZERO,4
  335.        MOV  *R3+,R0
  336.        LDCR R8,4
  337.        MOV  R0,*R7+
  338.        CI   R3,SECBUF+512
  339.        JNE  WRT18E
  340. WRT18F B    @WRIT30
  341.  
  342. WRIT19 MOV  @2(R1),R2        Get next AU
  343.        JNE  WRIT18
  344.  
  345. * It looks like we have to allocate another AU for the
  346. * file.  Here we go.
  347.  
  348.        MOV  R5,R0            Save pointer
  349.        MOV  *R1,R7           Set preferred AU
  350.        INC  R7
  351.        LI   R8,1             We want 1 AU
  352.        LI   R3,256           In case we don't get the one we want
  353.        LDCR @ZERO,4
  354.        BLWP @ALLOC
  355.        JEQ  WRIT20
  356.        BL   @DSRERR
  357.        DATA >0600            Device error
  358.  
  359. WRIT20 CI   R4,0
  360.        JNE  WRIT21
  361.        BL   @DSRERR
  362.        DATA >0400            Out of space error
  363.  
  364. WRIT21 MOV  R5,R2            Save the AU
  365.        MOV  R0,R5            Restore pointer
  366.        LDCR @B02,4
  367.        MOV  @4(R5),R8        Get FDR address
  368.        LDCR @2(R5),4
  369.        INC  @34(R8)          Increment # of AUs allocated
  370.        LDCR @B04,4           Set # of sectors allocated
  371.        MOV  R6,R3
  372.        SRL  R3,8
  373.        SLA  R3,1
  374.        MOV  @SAUTBL(R3),R3
  375.        LDCR @B02,4
  376.        LDCR @2(R5),4
  377.        A    R3,@14(R8)
  378.        C    R7,R2            Did we get the AU we wanted?
  379.        JEQ  WRIT23
  380.  
  381.        INCT R1               If not, add a new entry to chain
  382.        MOV  R2,*R1+
  383. WRIT23 MOV  R2,*R1
  384.  
  385.        LDCR @B02,4
  386.        MOV  R2,@50(R5)       Store current AU
  387.        CLR  @58(R5)          Set buffer size to 256
  388.  
  389. * Now see if we can use a 512 byte buffer
  390.  
  391.        B    @WRT6A
  392.  
  393.  
  394. **
  395. *
  396. * Here is the infamous WRIT30.  Here is where we store the
  397. * record in the file buffer and set the buffer modified flag
  398. *
  399. **
  400.  
  401. WRIT30 LDCR @ZERO,4
  402.        MOVB @PABBUF+3,@VDPWA Set VDP read address to user's buffer
  403.        NOP
  404.        MOVB @PABBUF+2,@VDPWA
  405.  
  406.        LDCR @B02,4
  407.        MOV  @54(R5),R1       Get pointer in buffer
  408.        MOV  @4(R5),R2        Get FDR address
  409.        SETO @60(R5)          Set buffer modified flag
  410.  
  411. * If we are doing variable length files, then we have to
  412. * put the byte count in first
  413.  
  414.        LDCR @2(R5),4         Select bank with FDR
  415.        MOVB @12(R2),R7       Get file flags
  416.        ANDI R7,>8000
  417.        JEQ  WRIT31
  418.  
  419.        LDCR @ZERO,4
  420.        MOVB @PABBUF+5,R4     Get character count
  421.        LDCR @B02,4
  422.        LDCR @3(R5),4
  423.        MOVB R4,*R1+
  424.        JEQ  WRIT34
  425.        JMP  WRIT32
  426.  
  427. WRIT31 MOVB @17(R2),R4       Get fixed record size from FDR
  428.  
  429. WRIT32 LDCR @B02,4
  430.        SRL  R4,8
  431.  
  432.        LDCR @3(R5),4         Get buffer bank swapped in
  433.  
  434. WRIT33 MOVB @VDPRD,*R1+
  435.        DEC  R4
  436.        JNE  WRIT33
  437.  
  438. * If we're doing variable length files, put in a new
  439. * end of sector marker after the record.
  440.  
  441.        CI   R7,0
  442.        JEQ  WRIT36
  443. WRIT34 MOVB @B255,*R1
  444.        MOV  R1,R7            Set end of file offset
  445.        SWPB R7
  446.        LDCR @B02,4
  447.        MOV  @62(R5),R8       Get sector number
  448.        SWPB R8
  449.        LDCR @2(R5),4
  450.        MOVB R7,@16(R2)       Save end of file offset
  451.        MOV  R8,@18(R2)       Save # of level 3 records
  452.  
  453. WRIT35 LDCR @B02,4
  454.        MOV  R1,@54(R5)       Save pointer within buffer
  455.  
  456.        LDCR @ZERO,4
  457.        B    @DSRRT
  458.  
  459. * For fixed length files, we need to increment the record #
  460. * and if it's greater than the last record written, update
  461. * the FDR.
  462.  
  463. WRIT36 LDCR @B02,4
  464.        INC  @62(R5)          Increment the record #
  465.        MOV  @62(R5),R0
  466.        MOV  @4(R5),R2        Get FDR address
  467.        LDCR @2(R5),4         Select BANK with FDR
  468.        MOV  @18(R2),R3       Get # of level 3 records written
  469.        SWPB R3
  470.        C    R0,R3
  471.        JL   WRIT35
  472.        SWPB R0
  473.        MOV  R0,@18(R2)       Update Level 3 field in FDR
  474.        JMP  WRIT35
  475.  
  476.  
  477. **
  478. *
  479. *  Here is where we handle relative I/O.  If we are trying
  480. *  to write past the end of file, we need to allocate some
  481. *  more AUs
  482. *
  483. **
  484.  
  485. WRIT50
  486.  
  487. * Step 1: Make sure the file was opened for relative access
  488.  
  489.        LDCR @B02,4       Select RAM bank 2
  490.        MOVB @57(R5),R0
  491.        JNE  WRIT51
  492.  
  493.        BL   @DSRERR
  494.        DATA >0700        File error
  495.  
  496. WRIT51 LDCR @ZERO,4
  497.        MOV  @PABADR,R10       Increment record number in
  498.        AI   R10,6             caller's PAB
  499.        ORI  R10,>4000
  500.        SWPB R10
  501.        MOVB R10,@VDPWA
  502.        SWPB R10
  503.        MOVB R10,@VDPWA
  504.        MOV  @PABBUF+6,R10
  505.        INC  R10
  506.        MOVB R10,@VDPWD
  507.        SWPB R10
  508.        MOVB R10,@VDPWD
  509.  
  510.        MOV  @PABBUF+6,R10     Get record # to write
  511.        LDCR @B02,4
  512.        MOV  @4(R5),R1         Get FDR address
  513.        LDCR @2(R5),4
  514.        MOV  @18(R1),R2        See if we're writing past EOF
  515.        SWPB R2
  516.        C    R10,R2
  517.        JHE  WRIT53            If so, extend the file
  518.  
  519. WRIT52 BL   @POSIT
  520.        B    @WRIT30
  521.  
  522. WRIT53
  523.  
  524. * Here we're writing past the end of the file.  Let's begin
  525. * by computing the number of AU's that will be needed.
  526.  
  527.        CLR  R9
  528. *      DEC  R10
  529.        MOVB @13(R1),R0       Get # of records/sector
  530.        MOV  @34(R1),R2       Get # of AU's allocated
  531.        SRL  R0,8
  532.        DIV  R0,R9            R9 now has # of sectors needed
  533.  
  534.        LDCR @B04,4
  535.        MOV  R6,R3
  536.        SRL  R3,8
  537.        SLA  R3,1
  538.        CLR  R8
  539.        DIV  @SAUTBL(R3),R8   R8 now has # of AU's we need
  540.        INC  R8
  541.        S    R2,R8            Subtract the # of AU's we have
  542.  
  543. WRIT54
  544.        CI   R8,0
  545.        JNE  WRIT55
  546.        LDCR @B04,4           Get # of sectors / AU
  547.        MOV  R6,R3
  548.        SRL  R3,8
  549.        SLA  R3,1
  550.        MOV  @SAUTBL(R3),R3
  551.  
  552.        LDCR @ZERO,4
  553.        MOV  @PABBUF+6,R10    Update # of level 3 records
  554.        LDCR @B02,4
  555.        MOV  @4(R5),R1        Get FDR address
  556.        LDCR @2(R5),4
  557.        INC  R10
  558.        SWPB R10
  559.        MOV  R10,@18(R1)
  560.        MOV  @34(R1),R7       Multiply AU's by secotrs/AU
  561.        MPY  R3,R7            to get # of sectors allocated
  562.        MOV  R8,@14(R1)
  563.        JMP  WRIT52
  564.  
  565. * Here is where we allocate some more AU's for the file
  566.  
  567. WRIT55
  568.        CLR  R7               No preferred starting AU
  569.        LI   R3,256           AU boundry
  570.        LDCR @ZERO,4
  571.        MOV  R5,R0            Save R5
  572.        BLWP @ALLOC
  573.        JEQ  WRIT56
  574.  
  575.        BL   @DSRERR
  576.        DATA >0600            Device error
  577.  
  578. WRIT56 CI   R4,0
  579.        JNE  WRIT57
  580.        BL   @DSRERR
  581.        DATA >0400            Out of space
  582.  
  583. WRIT57
  584.        MOV  R5,R2            Save starting AU
  585.        MOV  R0,R5            Restore R5
  586.  
  587. * Now put the new AU's in the data chain
  588.  
  589.        LDCR @B02,4
  590.        MOV  @4(R5),R1        Get FDR address
  591.        LDCR @2(R5),4
  592.        A    R4,@34(R1)       Update # of AU's allocated
  593.        S    R4,R8            Subtract from # needed
  594.        AI   R1,40            Point to data chain
  595. WRIT58
  596.        C    *R1,@ZERO
  597.        JEQ  WRIT59
  598.        AI   R1,4
  599.        JMP  WRIT58
  600.  
  601. WRIT59 DECT R1
  602.        MOV  *R1,R10
  603.        INC  R10
  604.        C    R2,R10
  605.        JNE  WRIT60
  606.        A    R4,*R1
  607.        JMP  WRIT54
  608.  
  609. WRIT60 INCT R1
  610.        MOV  R2,*R1+
  611.        MOV  R2,*R1
  612.        A    R4,*R1
  613.        DEC  *R1
  614.        JMP  WRIT54
  615.